/*
 *  util.c
 *
 *  MyQQ utilities
 *
 *  Copyright (C) 2008  Huang Guan
 *
 *  2008-7-15 Created.
 *  2009-3-22 Add msleep.
 *
 */

#ifdef __WIN32__
#include <io.h>
#include <windows.h>
#else
#include <sys/stat.h>
#endif
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include "qqsocket.hpp"
#include "debug.hpp"
#include "qqdef.hpp"
#include "util.hpp"
#include "memory.hpp"

/* Map for purple smiley convert to qq, need qsort */
qq_emoticon emoticons_std[] = {
        {14,0x4f, "/:)"},
        {1,0x42, "/:~"},
        {2,0x43, "/:*"},
        {3,0x44, "/:|"},
        {4,0x45, "/8-)"},
        {5,0x46, "/:<"},
        {6,0x47, "/:$"},
        {7,0x48, "/:x"},
        {8,0x49, "/:z"},
        {9,0x4a, "/:'"},
        {10,0x4b, "/:-|"},
        {11,0x4c, "/:@"},
        {12,0x4d, "/:P"},
        {13,0x4e, "/:D"},
        {0,0x41, "/:O"},
        {15,0x73, "/:("},
        {16,0x74, "/:+"},
        {17,0xa1, "/--b"},
        {18,0x76, "/:Q"},
        {20,0x8a, "/;P"},
        {21,0x8b, "/;-D"},
        {22,0x8c, "/;d"},
        {23,0x8d, "/;o"},
        {24,0x8e, "/:g"},
        {8, 0x8f, "/|-)"},
        {26,0x78, "/:!"},
        {27,0x79, "/:L"},
        {28,0x7a, "/:>"},
        {29,0x7b, "/:;"},
        {30,0x90, "/;f"},
        {31,0x91, "/:-S"},
        {32,0x92, "/?"},
        {33,0x93, "/;x"},
        {34,0x94, "/;@"},
        {35,0x95, "/:8"},
        {36,0x96, "/;!"},
        {37,0x97, "/!!!"},
        {38,0x98, "/xx"},
        {39,0x99, "/bye"},
        {97,0xa2, "/wipe"},
        {98,0xa3, "/dig"},
        {99,0xa4, "/handclap"},
        {100,0xa5, "/&-("},
        {101,0xa6, "/B-)"},
        {102,0xa7, "/<@"},
        {103,0xa8, "/@>"},
        {104,0xa9, "/:-O"},
        {105,0xaa, "/>-|"},
        {106,0xab, "/P-("},
        {107,0xac, "/:'|"},
        {108,0xad, "/X-)"},
        {109,0xae, "/:*"},
        {110,0xaf, "/@x"},
        {111,0xb0, "/8*"},
        {112,0xb1, "/pd"},
        {89,0x61, "/<W>"},
        {113,0xb2, "/beer"},
        {114,0xb3, "/basketb"},
        {115,0xb4, "/oo"},
        {60,0x80, "/coffee"},
        {61,0x81, "/eat"},
        {46,0x7c, "/pig"},
        {63,0x62, "/rose"},
        {64,0x63, "/fade"},
        {65,0xb5, "/showlove"},
        {51,0x65, "/heart"},
        {52,0x66, "/break"},
        {53,0x67, "/cake"},
        {54,0x9c, "/li"},
        {55,0x9d, "/bome"},
        {56,0x9e, "/kn"},
        {57,0x5e, "/footb"},
        {117,0xb6, "/ladybug"},
        {59,0x89, "/shit"},
        {73,0x6e, "/moon"},
        {74,0x6b, "/sun"},
        {69,0x68, "/gift"},
        {49,0x7f, "/hug"},
        {76,0x6f, "/strong"},
        {77,0x70, "/weak"},
        {78,0x88, "/share"},
        {118,0xb7, "/@)"},
        {119,0xb8, "/jj"},
        {120,0xb9, "/@@"},
        {121,0xba, "/bad"},
        {122,0xbb, "/loveu"},
        {123,0xbc, "/no"},
        {124,0xbd, "/ok"},
        {42,0x5c, "/love"},
        {85,0x56, "/<L>"},
        {43,0x58, "/jump"},
        {41,0x5a, "/shake"},
        {86,0x5b, "/<O>"},
        {125,0xbe, "/circle"},
        {126,0xbf, "/kotow"},
        {127,0xc0, "/turn"},
        {19,0x77, "/:t"},
        {79,0xa0, "/victory"},
        {128,0xc1, "/skip"},
        {99,0xc2, "/oY"},
        {100,0xc3, "/#-O"},
        {101,0xc4, "/hiphop"},
        {102,0xc5, "/kiss"},
        {103,0xc6, "/<&"},
        {105,0xc7, "/&>"},
        {106,0x75, "/:#"},
        {107,0x59, "/go"},
        {108,0x57, "/find"},
        {109,0x55, "/&"},
        {110,0x7d, "/cat"},
        {111,0x7e, "/dog"},
        {112,0x9a, "/$"},
        {113,0x9b, "/(!)"},
        {114,0x60, "/cup"},
        {115,0x9f, "/music"},
        {116,0x82, "/pill"},
        {117,0x64, "/kiss"},
        {118,0x83, "/meeting"},
        {119,0x84, "/phone"},
        {120,0x85, "/time"},
        {121,0x86, "/email"},
        {122,0x87, "/tv"},
        {123,0x50, "/<D>"},
        {124,0x51, "/<J>"},
        {125,0x52, "/<H>"},
        {126,0x53, "/<M>"},
        {127,0x54, "/<QQ>"},
        {128,0x5d, "/<B>"},
        {129,0x5f, "/<U>"},
        {130,0x69, "/<!!>"},
        {131,0x6a, "/<~>"},
        {132,0x6c, "/<Z>"},
        {133,0x6d, "/<*>"},
        {134,0x71, "/<00>"},
        {135,0x72, "/<11>"},
        {0,0, NULL}
};
qq_emoticon emoticons_sym[] = {};
/*        {0x41, "/jy"},
        {0x42, "/pz"},
        {0x43, "/se"},
        {0x44, "/fd"},
        {0x45, "/dy"},
        {0x46, "/ll"},
        {0x47, "/hx"},
        {0x48, "/bz"},
        {0x49, "/shui"},
        {0x4a, "/dk"},
        {0x4b, "/gg"},
        {0x4c, "/fn"},
        {0x4d, "/tp"},
        {0x4e, "/cy"},
        {0x4f, "/wx"},
        {0x50, "/dd"},
        {0x51, "/mn"},
        {0x52, "/hl"},
        {0x53, "/mamao"},
        {0x54, "/qz"},
        {0x55, "/mm"},
        {0x56, "/fw"},
        {0x57, "/zhao"},
        {0x58, "/tiao"},
        {0x59, "/shan"},
        {0x5a, "/fad"},
        {0x5b, "/oh"},
        {0x5c, "/aiq"},
        {0x5d, "/bj"},
        {0x5e, "/zq"},
        {0x5f, "/qsh"},
        {0x60, "/bei"},
        {0x61, "/xig"},
        {0x62, "/mg"},
        {0x63, "/dx"},
        {0x64, "/wen"},
        {0x65, "/xin"},
        {0x66, "/xs"},
        {0x67, "/dg"},
        {0x68, "/lw"},
        {0x69, "/xy"},
        {0x6a, "/duoy"},
        {0x6b, "/ty"},
        {0x6c, "/xr"},
        {0x6d, "/xixing"},
        {0x6e, "/yl"},
        {0x6f, "/qiang"},
        {0x70, "/ruo"},
        {0x71, "/nv"},
        {0x72, "/nan"},
        {0x73, "/ng"},
        {0x74, "/kuk"},
        {0x75, "/feid"},
        {0x76, "/zk"},
        {0x77, "/tu"},
        {0x78, "/jk"},
        {0x79, "/sweat"},
        {0x7a, "/hanx"},
        {0x7b, "/db"},
        {0x7c, "/zt"},
        {0x7d, "/maom"},
        {0x7e, "/xg"},
        {0x7f, "/yb"},
        {0x80, "/coffee"},
        {0x81, "/fan"},
        {0x82, "/yw"},
        {0x83, "/hy"},
        {0x84, "/dh"},
        {0x85, "/sj"},
        {0x86, "/yj"},
        {0x87, "/ds"},
        {0x88, "/ws"},
        {0x89, "/bb"},
        {0x8a, "/tx"},
        {0x8b, "/ka"},
        {0x8c, "/by"},
        {0x8d, "/am"},
        {0x8e, "/jie"},
        {0x8f, "/kun"},
        {0x90, "/fendou"},
        {0x91, "/zhm"},
        {0x92, "/yiw"},
        {0x93, "/xu"},
        {0x94, "/yun"},
        {0x95, "/zhem"},
        {0x96, "/shuai"},
        {0x97, "/kl"},
        {0x98, "/qiao"},
        {0x99, "/zj"},
        {0x9a, "/qianc"},
        {0x9b, "/dp"},
        {0x9c, "/shd"},
        {0x9d, "/zhd"},
        {0x9e, "/dao"},
        {0x9f, "/yy"},
        {0xa0, "/shl"},
        {0xa1, "/lengh"},
        {0xa2, "/wipe"},
        {0xa3, "/kb"},
        {0xa4, "/gz"},
        {0xa5, "/qd"},
        {0xa6, "/huaix"},
        {0xa7, "/zhh"},
        {0xa8, "/yhh"},
        {0xa9, "/hq"},
        {0xaa, "/bs"},
        {0xab, "/wq"},
        {0xac, "/kk"},
        {0xad, "/yx"},
        {0xae, "/qq"},
        {0xaf, "/xia"},
        {0xb0, "/kel"},
        {0xb1, "/cd"},
        {0xb2, "/pj"},
        {0xb3, "/lq"},
        {0xb4, "/pp"},
        {0xb5, "/sa"},
        {0xb6, "/pc"},
        {0xb7, "/bq"},
        {0xb8, "/gy"},
        {0xb9, "/qt"},
        {0xba, "/cj"},
        {0xbb, "/aini"},
        {0xbc, "/bu"},
        {0xbd, "/hd"},
        {0xbe, "/zhq"},
        {0xbf, "/kt"},
        {0xc0, "/ht"},
        {0xc1, "/tsh"},
        {0xc2, "/hsh"},
        {0xc3, "/jd"},
        {0xc4, "/jw"},
        {0xc5, "/xw"},
        {0xc6, "/ztj"},
        {0xc7, "/ytj"},
        {0, NULL}
};*/
uint emoticons_sym_num = sizeof(emoticons_sym) / sizeof(qq_emoticon) - 1;;
uint emoticons_std_num = sizeof(emoticons_std) / sizeof(qq_emoticon) - 1;
static const char *emoticon_get(unsigned int symbol)
{
    if((symbol >= emoticons_sym[0].symbol) &&
     (symbol <= emoticons_sym[emoticons_sym_num - 2].symbol))
    {

        return emoticons_std[(symbol - emoticons_sym[0].symbol)*3].name;
    }
    else
    {
        return "";
    }
}
unsigned char emoticon_get_index(unsigned char symbol)
{
    unsigned char index =0;
    for(uint i=0;i<emoticons_std_num;i++)
    {
        if(symbol == emoticons_std[i].symbol)
        {
            //index = i;
            index = emoticons_std[i].index;
            DBG("emoticon_get_index: 0x%2x->%d",symbol,index);
            break;
        }
    }
    return index;
}
int mkdir_recursive( char* path, char tokchr )
{
        char *p;
        if( access( path, 0 ) == 0 )
                return 0;
        for( p=path; *p; p++ ){
                if( p>path && *p == tokchr ){
                        *p = 0;
                        if( access( path, 0 ) != 0 ){
#ifdef __WIN32__
                                mkdir( path );
#else
                                if( mkdir( path, S_IRWXU ) != 0 )
                                        return -1;
#endif
                        }
                        *p = tokchr;
                }
        }
#ifdef __WIN32__
        return mkdir( path );
#else
        return mkdir( path, S_IRWXU );
#endif
}
int pack_faces( char* src, char* dst, int outlen )
{
    char * p, *q;
    p = src;	q = dst;
    int symbol = 0;
    while( *p ){
        if((*(p) == '[') &&
           (*(p+1) == 'f') &&
           (*(p+2) == 'a') &&
           (*(p+3) == 'c') &&
           (*(p+4) == 'e') &&
           (*(p+5) == ':') )
        {
            char* substr = strstr(p,"]");
            if(substr>0)
            {
                int pos = substr - p - 6;
                char sfaceid[4] = "";
                strncpy(sfaceid,p + 6,pos);

                symbol = atoi(sfaceid);
                *(q++) = 0x15;
                *(q++) = 0x14;
                *(q++) = symbol;
                *(q++) = 0x15;
                p = p + 6 + pos + 1;
            }
        }
        else
        {
            *(q++) = *p;
            p++;
        }
    }
    *q = 0;
    return 0;
}

int trans_faces( char* src, char* dst, int outlen )
{
        char * p, *q;
        p = src;	q = dst;
        while( *p ){
                if( *(p++) == 0x14 ){
                        if( (int)(q-dst) < outlen - 10 )
                                q += sprintf( q, "[face:%u]", *(p++) );
                }else{
                        if( (int)(q-dst) < outlen )
                                *(q++) = *(p-1);
                }
        }
        *q = 0;
        return (int)(q-dst);
}

//2009-2-7 9:20 Huang Guan
//get middle value from a string by the left and the right.
char* mid_value( char* str, const char* left, const char* right, char* out, int outlen )
{
        char* beg, * end, t;
        beg = strstr( str, left );
        if( beg ){
                beg += strlen(left);
                if( right ){
                        end = strstr( beg, right );
                }else{
                        end = beg + strlen(beg);
                }
                if( end ){
                        t = *end; *end = 0;
                        strncpy( out, beg, outlen );
                        *end = t;
                        return end;	//returns the end
                }
        }
        *out = '\0';
        return str;
}

//2009-2-7 9:21 Huang Guan
//Download a file
//http://verycode.qq.com/getimage?fromuin=942011793&touin=357339036&appt=1&flag=1
//GET  HTTP/1.1
int http_request( int* http_sock, char* url, char* session, char* data, int* datalen )
{
        char host_name[32], uri[101], *header, *next, tmp[16];
        int len, data_len;
        //get host name
        next = mid_value( url, "//", "/", host_name, 31 );
        next = mid_value( next, "/", NULL, uri, 100 );
        //connect
        *http_sock = qqsocket_create( TCP, NULL, 0 );
        if( *http_sock <= 0 )	return -3;
        qqsocket_connect( *http_sock, host_name, 80 );
        NEW( header, KB(4) );
        sprintf( header, "GET %s HTTP/1.1\r\n\r\n", uri );
        qqsocket_send( *http_sock, (uchar*)header, strlen(header) );
        len = qqsocket_recv( *http_sock, (uchar*)header, KB(4) );
//	puts( header );
        if( len>0 ){
                next = mid_value( header, "Content-Length: ", "\r\n", tmp, 15 );
                data_len = atoi( tmp );
                next = mid_value( header, "getqqsession:", "\r\n", session, 127 );
                while( len < data_len ){
                        int ret = qqsocket_recv( *http_sock, (uchar*)(header + len), KB(4)-len );
                        if( ret > 0 )	len += ret;	else	break;
                }
                next = strstr( header, "\r\n\r\n" ) + 4;
                if( next ){
                        if( *datalen > data_len ){
                                memcpy( (void*)data, (void*)next, data_len );
                                *datalen = data_len;
                        }else{
                                DBG("datalen is too small.");
                        }
                }
        }
        DEL( header );
        qqsocket_close( *http_sock );
        return 0;
}

#ifdef __WIN32__
void msleep( unsigned int ms )
{
        Sleep( ms );
}
#endif
int get_splitable_pos( char* buf, int pos )
{
        //pos = 699
        if( (uchar)buf[pos]>=0x80 && (uchar)buf[pos]<=0xBF ){
                do
                        pos--;
                while( pos && (uchar)buf[pos]<0xC2 );
        }
        return pos;	//buf[pos]不可取
}
#ifndef __linux__
char *strtok_r(char *str, const char *delim, char **save)
{
    char *res, *last;

    if( !save )
        return strtok(str, delim);
    if( !str && !(str = *save) )
        return NULL;
    last = str + strlen(str);
    if( (*save = res = strtok(str, delim)) )
    {
        *save += strlen(res);
        if( *save < last )
            (*save)++;
        else
            *save = NULL;
    }
    return res;
}
#endif
